package tests.jdl.databaseObjects;

import jdl.databaseObjects.DbCollection;
import jdl.databaseObjects.DbObject;
import jdl.databaseObjects.ObjectAlreadyExistsException;
import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

public class DbCollection_Test {
	private DbCollectionImpl collection;

	@Before
	public void setUp() {
		collection = new DbCollectionImpl();
	}

	@Test
	public void getCount_collectionsHasOneElement() {
		DbObject object = Mockito.mock(DbObject.class);
		collection.addObject(object);
		Assert.assertEquals(1, collection.getCount());
	}

	@Test
	public void getCount_collectionsHasTwoElements() {
		DbObject firstObject = Mockito.mock(DbObject.class);
		collection.addObject(firstObject);

		DbObject secondObject = Mockito.mock(DbObject.class);
		collection.addObject(secondObject);

		Assert.assertEquals(2, collection.getCount());
	}

	@Test
	public void add() throws ObjectAlreadyExistsException {
		DbObject object = Mockito.mock(DbObject.class);
		collection.add(object);

		Assert.assertEquals(1, collection.getCount());
		Assert.assertEquals(object, collection.getObjectByIndex(0));
	}

	@Test(expected = ObjectAlreadyExistsException.class)
	public void add_objectAlreadyExists() throws ObjectAlreadyExistsException {
		DbObject firstObject = Mockito.mock(DbObject.class);
		Mockito.when(firstObject.getName()).thenReturn("obj");

		DbObject secondObject = Mockito.mock(DbObject.class);
		Mockito.when(secondObject.getName()).thenReturn("obj");

		collection.add(firstObject);
		collection.add(secondObject);
	}

	@Test
	public void getObjectByIndex() {
		DbObject object = Mockito.mock(DbObject.class);
		collection.addObject(object);
		Assert.assertEquals(object, collection.getObjectByIndex(0));
	}

	@Test
	public void getObjectByName_collectionIsEmpty() {
		Assert.assertNull(collection.getObjectByName("hello"));
	}

	@Test
	public void getObjectByName_collectionHasOneElement() {
		DbObject object = Mockito.mock(DbObject.class);
		Mockito.when(object.getName()).thenReturn("ID");
		collection.addObject(object);
		Assert.assertEquals(object, collection.getObjectByName("id"));
		Assert.assertNull(collection.getObjectByName("qwerty"));
	}

	@Test
	public void getObjectByName_collectionHasTwoElements() {
		DbObject firstObject = Mockito.mock(DbObject.class);
		Mockito.when(firstObject.getName()).thenReturn("firstObject");
		collection.addObject(firstObject);
		DbObject secondObject = Mockito.mock(DbObject.class);
		Mockito.when(secondObject.getName()).thenReturn("secondObject");
		collection.addObject(secondObject);
		Assert.assertEquals(firstObject,
				collection.getObjectByName("firstObject"));
		Assert.assertEquals(secondObject,
				collection.getObjectByName("secondObject"));
	}

	@Test(expected = IllegalArgumentException.class)
	public void getObjectByName_NameIsNull() {
		collection.getObjectByName(null);
	}

	@Test(expected = IllegalArgumentException.class)
	public void getObjectByName_NameIsEmpty() {
		collection.getObjectByName("");
	}

	class DbCollectionImpl extends DbCollection<DbObject> {
		@Override
		public void addObject(DbObject object) {
			super.addObject(object);
		}

		@Override
		public DbObject getObjectByName(String name) {
			return super.getObjectByName(name);
		}
	}
}
